﻿#pragma once
#include <thread>                  // 用于多线程编程
#include <log_wapper.hpp>          // 包含日志记录的工具头文件
#include <define.h>                // 包含通用定义的头文件
#include <lightning.h>             // 包含 lightning 相关的头文件
#include "event_center.hpp"        // 包含事件中心相关的头文件
#include <market_api.h>            // 包含市场 API 的头文件
#include <trader_api.h>            // 包含交易 API 的头文件
#include <params.hpp>              // 包含参数处理的头文件
#include "trading_section.h"       // 包含交易部分的头文件

class context
{
public:

    // 构造函数，标记为 noexcept 表示不抛出异常
    context() noexcept;

    // 虚析构函数，标记为 noexcept 表示不抛出异常
    virtual ~context() noexcept;
    
private:

    // 禁止拷贝构造函数
    context(const context&) noexcept = delete;

    // 禁止赋值操作符
    context& operator=(const context&) noexcept = delete;

    // 禁止移动构造函数
    context(context&&) noexcept = delete;

    // 禁止移动赋值操作符
    context& operator=(context&&) noexcept = delete;

private:
    
    bool _is_runing;                // 标记上下文是否正在运行
    
    // 实时回调函数
    tick_callback _tick_callback;
    cycle_callback _init_callback;
    cycle_callback _update_callback;
    cycle_callback _destroy_callback;
    
    // 实时事件，用于高频策略
    order_event realtime_event;
    
    // 实时的线程
    std::thread* _realtime_thread;
    
    daytm_t _last_tick_time;        // 上一次的时间戳
    
    uint32_t _max_position;         // 最大持仓量

    int16_t _bind_cpu_core;         // 绑定的 CPU 核心
    int16_t _thread_priority;       // 线程优先级

    uint32_t _loop_interval;        // 循环间隔时间
    
    std::map<code_t, tick_info> _previous_tick; // 存储以前的 tick 信息

    daytm_t _last_order_time;       // 上一次订单的时间戳

    std::map<code_t, today_market_info> _today_market_info; // 今日市场信息
    std::map<code_t, order_statistic> _statistic_info;      // 订单统计信息

    position_map _position_info;    // 持仓信息
    entrust_map _order_info;        // 订单信息

    std::map<std::string, std::string> _include_config; // 配置文件的包含设置

    std::shared_ptr<trading_section> _section_config;   // 交易部分的配置

public:

    // 加载交易数据
    void load_trader_data() noexcept;

    // 启动服务
    bool start_service() noexcept;
    
    // 更新服务
    void update() noexcept;

    // 停止服务
    bool stop_service() noexcept;

    // 绑定实时事件和回调函数
    void bind_realtime_event(const order_event& event_cb, cycle_callback init_cb, cycle_callback update_cb, cycle_callback destroy_cb) noexcept
    {
        realtime_event = event_cb;
        this->_init_callback = init_cb;
        this->_update_callback = update_cb;
        this->_destroy_callback = destroy_cb;
    }

    // 下单
    estid_t place_order(offset_type offset, direction_type direction, const code_t& code, uint32_t count, double_t price, order_flag flag) noexcept;
    
    // 撤单
    bool cancel_order(estid_t estid) noexcept;
    
    // 获取持仓信息
    const position_info& get_position(const code_t& code) const noexcept;
    
    // 获取订单信息
    const order_info& get_order(estid_t estid) const noexcept;

    // 查找订单
    void find_orders(std::vector<order_info>& order_result, std::function<bool(const order_info&)> func) const noexcept;

    // 获取总持仓量
    uint32_t get_total_position() const noexcept;

    // 订阅 tick 数据
    void subscribe(const std::set<code_t>& tick_data, tick_callback tick_cb) noexcept;

    // 取消订阅 tick 数据
    void unsubscribe(const std::set<code_t>& tick_data) noexcept;
    
    // 获取最后时间
    daytm_t get_last_time() noexcept;

    // 获取最后订单时间
    daytm_t last_order_time() noexcept;

    // 获取订单统计信息
    const order_statistic& get_order_statistic(const code_t& code) const noexcept;

    // 获取交易日
    uint32_t get_trading_day() noexcept;

    // 获取收盘时间
    daytm_t get_close_time() const noexcept;
    
    // 判断是否在交易中
    bool is_in_trading() const noexcept;

    // 获取最大持仓量
    inline uint32_t get_max_position() const noexcept
    {
        return _max_position;
    }

    // 获取今日市场信息
    const today_market_info& get_today_market_info(const code_t& id) const noexcept;

    // 获取总待处理订单数
    uint32_t get_total_pending() noexcept;

    // 获取以前的 tick 信息
    const tick_info& get_previous_tick(const code_t& code) noexcept;

    // 获取包含配置的值
    const char* get_include_config(const char* key) noexcept;

protected:

    // 获取所有统计信息
    order_statistic get_all_statistic() const noexcept;

private:

    // 检查跨日情况
    void check_crossday() noexcept;

    // 处理委托事件
    void handle_entrust(const std::vector<std::any>& param) noexcept;

    // 处理成交事件
    void handle_deal(const std::vector<std::any>& param) noexcept;

    // 处理交易事件
    void handle_trade(const std::vector<std::any>& param) noexcept;

    // 处理撤单事件
    void handle_cancel(const std::vector<std::any>& param) noexcept;

    // 处理 tick 事件
    void handle_tick(const std::vector<std::any>& param) noexcept;

    // 处理错误事件
    void handle_error(const std::vector<std::any>& param) noexcept;

    // 计算持仓
    void calculate_position(const code_t& code, direction_type dir_type, offset_type offset_type, uint32_t volume, double_t price) noexcept;
    
    // 冻结扣减
    void frozen_deduction(const code_t& code, direction_type dir_type, offset_type offset_type, uint32_t volume) noexcept;
    
    // 解冻扣减
    void unfreeze_deduction(const code_t& code, direction_type dir_type, offset_type offset_type, uint32_t volume) noexcept;

    // 记录待处理订单
    void record_pending(const code_t& code, direction_type dir_type, offset_type offset_type, uint32_t volume) noexcept;

    // 恢复待处理订单
    void recover_pending(const code_t& code, direction_type dir_type, offset_type offset_type, uint32_t volume) noexcept;

    // 打印持仓信息
    inline void print_position(const char* title) noexcept
    {
        if (!_position_info.empty())
        {
            LOG_INFO("print_position : ", title);
        }
        for (const auto& it : _position_info)
        {
            const auto& pos = it.second;
            LOG_INFO("position :", pos.id.get_id(), "today_long(", pos.today_long.postion, pos.today_long.frozen, ") today_short(", pos.today_short.postion, pos.today_short.frozen, ") yestoday_long(", pos.history_long.postion, pos.history_long.frozen, ") yestoday_short(", pos.history_short.postion, pos.history_short.frozen, ")");
            LOG_INFO("pending :", pos.id.get_id(), pos.long_pending, pos.short_pending);
        }
    }

protected:

    // 初始化配置
    void init(const params& control_config, const params& include_config, bool reset_trading_day=false) noexcept;

public:

    // 纯虚函数：获取交易 API 接口
    virtual trader_api& get_trader() noexcept = 0;

    // 纯虚函数：获取市场 API 接口
    virtual market_api& get_market() noexcept = 0;

    // 纯虚函数：更新
    virtual void on_update() noexcept = 0;

    // 纯虚函数：判断是否结束
    virtual bool is_terminaled() noexcept = 0;
};
